﻿// testGame.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <Windows.h>
#include <map>
#include "AsmCode.h"
#include <ImageHlp.h>
#include "dll.h"
#include "tools.h"
ULONG64 value = 0x123456;

HANDLE handle[5] = { 0 };

VOID test1() {
	HMODULE hmodule = LoadLibraryA("user32.dll");
	std::cout << "Hello World!\n";
	while (1) {
		std::cout << std::hex << "vaule addres " << &value << std::endl;

		Sleep(3000);
	}
}

DWORD WINAPI workThread1(PVOID context) {


	for (int i = 0; i < 10; i++) {
		printf("---------------1workThread%d  in %x ----------------\r\n",i, GetCurrentThreadId());
		WaitForSingleObject(handle[0], INFINITE);
		printf("---------------1workThread%d  out ----------------\r\n",i);
	}

	return 0;
}
DWORD WINAPI workThread2(PVOID context) {

	for (int i = 0; i < 10; i++) {
		printf("---------------2workThread%d  in %x ----------------\r\n", i, GetCurrentThreadId());
		WaitForSingleObject(handle[0], INFINITE);
		printf("---------------2workThread%d  out ----------------\r\n", i);
	}
	system("pause");
	return 0;
}

VOID eventTest() {
		handle[0] = CreateSemaphoreA(NULL, 0, 3, NULL);

	CreateThread(NULL, NULL, workThread1, NULL, NULL, NULL);
	CreateThread(NULL, NULL, workThread2, NULL, NULL, NULL);

	system("pause");
	SetEvent(handle[0]);
}

VOID mutantTest() {


}

VOID SemaphoreTest() {

	CreateThread(NULL, NULL, workThread1, NULL, NULL, NULL);
	CreateThread(NULL, NULL, workThread2, NULL, NULL, NULL);
	handle[0] = CreateMutexA(NULL, FALSE, NULL);

	ReleaseMutex(handle[0]);

}

VOID GetForeginWindowTest() {

	
	
	while (1) {
		HANDLE hwnd = GetForegroundWindow();
		printf("%x\r\n",hwnd);
		Sleep(1000);
	}

}




VOID VadAttributeTest() {

	PVOID address = VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_NOACCESS);

	printf("address = %llx \r\n", address);

	system("pause");
	VirtualFree(address, 0x1000, MEM_RELEASE);
}
typedef enum _SECTION_INHERIT {
	ViewShare = 1,
	ViewUnmap = 2
} SECTION_INHERIT;



typedef struct _UNICODE_STRING {
	USHORT Length;
	USHORT MaximumLength;
#ifdef MIDL_PASS
	[size_is(MaximumLength / 2), length_is((Length) / 2)] USHORT* Buffer;
#else // MIDL_PASS
	_Field_size_bytes_part_opt_(MaximumLength, Length) PWCH   Buffer;
#endif // MIDL_PASS
} UNICODE_STRING;
typedef UNICODE_STRING* PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
	ULONG Length;
	HANDLE RootDirectory;
	PUNICODE_STRING ObjectName;
	ULONG Attributes;
	PVOID SecurityDescriptor;        // Points to type SECURITY_DESCRIPTOR
	PVOID SecurityQualityOfService;  // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES* POBJECT_ATTRIBUTES;
typedef NTSTATUS
(*NTAPI
ZwCreateSectionProc)(
	_Out_ PHANDLE SectionHandle,
	_In_ ACCESS_MASK DesiredAccess,
	_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
	_In_opt_ PLARGE_INTEGER MaximumSize,
	_In_ ULONG SectionPageProtection,
	_In_ ULONG AllocationAttributes,
	_In_opt_ HANDLE FileHandle
);

typedef NTSTATUS
(NTAPI
*ZwMapViewOfSectionProc)(
	_In_ HANDLE SectionHandle,
	_In_ HANDLE ProcessHandle,
	_Outptr_result_bytebuffer_(*ViewSize) PVOID* BaseAddress,
	_In_ ULONG_PTR ZeroBits,
	_In_ SIZE_T CommitSize,
	_Inout_opt_ PLARGE_INTEGER SectionOffset,
	_Inout_ PSIZE_T ViewSize,
	_In_ SECTION_INHERIT InheritDisposition,
	_In_ ULONG AllocationType,
	_In_ ULONG Win32Protect
);

typedef
NTSTATUS (*NTAPI ZwProtectVirtualMemoryProc)(
	IN HANDLE ProcessHandle,
	IN OUT PVOID* BaseAddress,
	IN OUT PSIZE_T RegionSize,
	IN ULONG NewProtect,
	OUT PULONG OldProtect
);
VOID FakeProcess() {

	HMODULE hModule = GetModuleHandleA("ntdll.dll");
	ZwMapViewOfSectionProc ZwMapViewOfSection = (ZwMapViewOfSectionProc)(GetProcAddress(hModule, "ZwMapViewOfSection"));
	ZwCreateSectionProc ZwCreateSection = (ZwCreateSectionProc)(GetProcAddress(hModule, "ZwCreateSection"));
	ZwProtectVirtualMemoryProc ZwProtectVirtualMemory = (ZwProtectVirtualMemoryProc)(GetProcAddress(hModule, "ZwProtectVirtualMemory"));
	HANDLE hSectionHandle = NULL;
	LARGE_INTEGER MaximumSize ={0};
	MaximumSize.QuadPart = 0x1000;
	DWORD st = ZwCreateSection(&hSectionHandle,
		SECTION_ALL_ACCESS,
		NULL,
		&MaximumSize,
		PAGE_READONLY,
		SEC_COMMIT,
		NULL);
	PVOID base = NULL;
	SIZE_T sizeView = 0x1000;

	if (st == 0) {
		LARGE_INTEGER sizeOffset = { 0 };
		st = ZwMapViewOfSection(hSectionHandle,
			GetCurrentProcess(),
			&base,
			0, MaximumSize.QuadPart,
			&sizeOffset,&sizeView, ViewShare, 0, PAGE_READONLY);
		printf("%x\r\n", st);
	}

	printf("base = %p\r\n", base);

	DWORD oldp;
	SIZE_T size = 0x1000;
	NTSTATUS status = ZwProtectVirtualMemory(GetCurrentProcess(), &base,&size, PAGE_READWRITE, &oldp);
	printf("ret = %d error = %x\r\n", status, GetLastError());
	system("pause");
}


int x = 0x12345678;

EXTERN_C int test2();

EXTERN_C int testAsm(int a, int b) {
	return a + b;
}


#ifdef __WIN32



VOID ExceptionEmu() {
	//编译模拟 throw
	//基于windows api
	RaiseException(0xC0000005, 0, 0, NULL);
	
}

#include <vector>
typedef struct _VehNode {

	LIST_ENTRY entry;

	ULONG refCount;

	ULONG encodeFunction;

}VehNode, * PVehNode;

typedef struct _HOOKINFO {
	ULONG_PTR HookAddr;
	ULONG_PTR newAddr;
	ULONG_PTR OrgModuleBase;
	ULONG_PTR OrgModuleSize;
	ULONG_PTR NewModuleBase;
	char OrgiCode[20];
	ULONG OrgLen;
	ULONG_PTR DispatchFunCall;
	bool isHook;


}HOOKINFO, * PHOOKINFO;

typedef struct _CONTEXTINFO {
	ULONG_PTR efl;
	ULONG_PTR _edi;
	ULONG_PTR _esi;
	ULONG_PTR _ebp;
	ULONG_PTR _esp;
	ULONG_PTR _ebx;
	ULONG_PTR _edx;
	ULONG_PTR _ecx;
	ULONG_PTR _eax;
}CONTEXTINFO, * PCONTEXTINFO;

std::map<ULONG_PTR, std::vector<HOOKINFO>> gHookInfo;


typedef VOID(WINAPI* HookCallback)(PCONTEXTINFO contextInfo);
typedef PVOID(WINAPI* PfnRtlPcToFileHeader)(PVOID PcValue, PVOID* BaseOfImage);


 LONG NTAPI VEHCallback(EXCEPTION_POINTERS* ExceptionInfo) {
	 

	 if (ExceptionInfo->ExceptionRecord->ExceptionCode == 0xC0000005) {

		 ULONG_PTR address = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress;
		 HOOKINFO hookInfo = { 0 };
		 PVOID imageBase = 0;
		 if (RtlPcToFileHeader((PVOID)address, &imageBase)) {
			 std::vector<HOOKINFO> infos = gHookInfo[(ULONG_PTR)imageBase];
			 for (auto item : infos) {
				 ULONG_PTR starAddress = item.HookAddr;
				 if ((starAddress & (~0xfff)) == (address & (~0xfff))) {
					 hookInfo = item;
				 }
			 }

			 if (hookInfo.HookAddr) {
				 ULONG_PTR newAddress = (ULONG_PTR)((PUCHAR)ExceptionInfo->ExceptionRecord->ExceptionAddress - (ULONG_PTR)hookInfo.OrgModuleBase + (ULONG_PTR)hookInfo.NewModuleBase);
				 ExceptionInfo->ContextRecord->Eip = newAddress;
				 return EXCEPTION_CONTINUE_EXECUTION;
			 }
		 }
	

	 }

	 return EXCEPTION_CONTINUE_SEARCH;
}

VOID VEHTest() {

	PVOID mem = AddVectoredExceptionHandler(TRUE, (PVECTORED_EXCEPTION_HANDLER)VEHCallback);
	int  x = 0,i = x / 0;
	
	system("pause");

}



int GetInsLen(LONG_PTR hookAddr, int minLen) {

	int len = 0;
	do {
		
		int temp = insn_len_x86_32((PVOID)hookAddr);
		hookAddr = temp + hookAddr;
		len += temp;
	} while (len < minLen);

	return len;
}

BOOLEAN VetHook() {

	PVehNode node = (PVehNode)AddVectoredExceptionHandler(TRUE, VEHCallback);
	if (node) {
		HMODULE hmodule = GetModuleHandleA("kernel32.dll");
		gHookInfo.clear();
		return TRUE;
	}
	return FALSE;
}



BOOLEAN AddHook(ULONG_PTR HookAddr, HookCallback newAddr) {

	
	
	
	HOOKINFO info;
	BOOLEAN isRet = FALSE;
	info.HookAddr = HookAddr;
	info.newAddr = (ULONG_PTR)newAddr;
	ULONG_PTR imageBase = NULL;

	if (RtlPcToFileHeader((PVOID)HookAddr,(PVOID*)&imageBase)) {
		std::vector<HOOKINFO> infos = gHookInfo[imageBase];

		PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)imageBase;
		PIMAGE_NT_HEADERS pNts = (PIMAGE_NT_HEADERS)(imageBase + pDos->e_lfanew);
		

		info.OrgModuleBase = imageBase;
		info.OrgModuleSize = pNts->OptionalHeader.SizeOfImage;
		SIZE_T retSize = 0;
		if (infos.empty()) {
			info.NewModuleBase = (ULONG_PTR)malloc(info.OrgModuleSize);
			memset((PVOID)info.NewModuleBase, 0, info.OrgModuleSize);
			int count  = info.OrgModuleSize >> 12;
			int i = 0;

			do {
				int error;
				ReadProcessMemory(GetCurrentProcess(), (PVOID)(info.OrgModuleBase + i * USN_PAGE_SIZE)
					, (PVOID)(info.NewModuleBase + i * USN_PAGE_SIZE),
					USN_PAGE_SIZE,
					&retSize);
				i++;
				count--;
			} while (count != 0);

			ULONG pro = 0;
			VirtualProtect((PVOID)info.NewModuleBase, info.OrgModuleSize, PAGE_EXECUTE_READWRITE, &pro);

		}
		else {

			info.NewModuleBase = infos[0].NewModuleBase;
		}

		

		//修改页属性
		ULONG pageOffset = HookAddr & 0xFFF;
		ULONG page = HookAddr & (~0xFFF);
		ULONG moduleOffset = HookAddr - imageBase;

		// 求需要hook的地址
		ULONG_PTR targetHookAddr = info.NewModuleBase + moduleOffset;

		//获取长度,保存原字节
		int inslen = GetInsLen(targetHookAddr, 5);
		memcpy(info.OrgiCode, (PVOID)targetHookAddr, inslen);
		info.OrgLen = inslen;

		//编写派发代码
		char bufCode[] = {
			0x60,
			0x9C,
			0x8D,0x04,0x24,
			0xB9,0x66,0x45,0x23,0x01,
			0x50,
			0xFF,0xD1,
			0x9D,0x61,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
			0x90,
		
			0x68,0x78,0x56,0x34,0x12,
			0xC3

		};

		ULONG pro = 0;

		info.DispatchFunCall = (ULONG_PTR)malloc(sizeof(bufCode));
		VirtualProtect((PVOID)info.DispatchFunCall, sizeof(bufCode), PAGE_EXECUTE_READWRITE,&pro);
		*(PULONG_PTR)&bufCode[6] = (ULONG_PTR)newAddr;
		*(PULONG_PTR)&bufCode[36] = targetHookAddr + inslen;
		memcpy((PUCHAR)bufCode + 15,info.OrgiCode,info.OrgLen);
		memcpy((PVOID)info.DispatchFunCall, bufCode, sizeof(bufCode));
		printf("hook address = %x \r\n", targetHookAddr);
		printf("Dispath address = %x \r\n", info.DispatchFunCall);
		//填入跳转代码
		char jmpCode[5] = { 0xe9,0 };
		*(PULONG_PTR)&jmpCode[1] = info.DispatchFunCall - targetHookAddr - 5;

		//开始挂页
		memcpy((PVOID)targetHookAddr, jmpCode, 5);

		VirtualProtect((PVOID)page, USN_PAGE_SIZE, PAGE_READONLY, &pro);
		infos.push_back(info);
		
		
		
		isRet = TRUE;
		info.isHook = isRet;
		gHookInfo[imageBase] = infos;
	}
	return TRUE;
}
VOID  OpenProcessHook(PCONTEXTINFO contextInfo) {

	printf("xxxxxxxxxxxxxxx\r\n");
	return;

}

VOID VehTest() {

	if (VetHook()) {

		HMODULE hModule = GetModuleHandleA("kernel32.dll");
		ULONG_PTR OpenProcess = (ULONG_PTR)GetProcAddress(hModule, "OpenProcess");
		AddHook((ULONG_PTR)OpenProcess, (HookCallback)OpenProcessHook);

	}

	printf("address = %x \r\n", OpenProcessHook);
	system("pause");

	OpenProcess(NULL, NULL, NULL);
}


typedef struct _EXCEPTIONSEHINFO{

	_EXCEPTIONSEHINFO* Next;
	PVOID Handler;
}EXCEPTIONSEHINFO,*PEXCEPTIONSEHINFO;

_EXCEPTION_DISPOSITION SehHandler(
	struct _EXCEPTION_RECORD* pException, 
	VOID* arg2,
	struct _CONTEXT* pContext, 
	VOID* arg4) {


	MessageBoxA(NULL, "SehHandler", NULL, NULL);
	pContext->Eip += 2;
	return ExceptionContinueSearch;

 }

VOID SehTest() {


	EXCEPTIONSEHINFO node = { 0 };
	EXCEPTIONSEHINFO* pre = NULL;

	_asm {
		mov eax, fs: [0] ;
		mov [pre], eax;

	}
	node.Next = pre;
	node.Handler = SehHandler;
	_asm {
		lea eax, [node];
		mov fs:[0] , eax;
	}

	int i = 0;
	int x = i / 0;
	printf("-------------------------\r\n");
	_asm {
		mov eax, [pre];
		mov fs : [0] , eax;
	}
}

DWORD FilterException(PEXCEPTION_POINTERS info) {
	if (info->ExceptionRecord->ExceptionCode == 0xC0000094) {
		printf("除0错误\r\n");
		info->ContextRecord->Eip += 2;
		return EXCEPTION_CONTINUE_EXECUTION;
	}
}
VOID ExceptionTest() {


	__try {

		int x = 0;
		int y = x / 0;
		printf("--------------------1-----------------------\r\n");

	}
	__except (FilterException(GetExceptionInformation())) {


		ULONG code = GetExceptionCode();
		printf("------------__except----2--------------------\r\n");


	}


}

typedef struct _SCOPEITEM {

	ULONG preTryIndex;
	ULONG filterFunc;//try except

	ULONG finallyFunc;//try finally

}SCOPEITEM, * PSCOPEITEM;


typedef struct _SCOPETABLE {
	ULONG_PTR A;
	ULONG_PTR B;
	ULONG_PTR C;
	ULONG_PTR D;
	SCOPEITEM item[1];

}SCOPETABLE,*PSCOPETABLE;


typedef struct _EXCEPTIONSEHINFO1 {

	_EXCEPTIONSEHINFO* Next;
	PVOID Handler;
	ULONG_PTR ScopeTable;
	ULONG_PTR currentTopLevel;
	ULONG_PTR ebp;
}EXCEPTIONSEHINFO1, * PEXCEPTIONSEHINFO1;

LPTOP_LEVEL_EXCEPTION_FILTER oldFunc;

LONG WINAPI filterFunc(
	_In_ struct _EXCEPTION_POINTERS* ExceptionInfo
) {

	MessageBoxA(NULL, NULL, NULL, NULL);
	return oldFunc(ExceptionInfo);
}
#endif // _WIN32


#include "MemoryModule.h"

int main()
{



	DWORD dwImageSize = sizeof(sysData);
	unsigned char* pMemory = (unsigned char*)malloc(dwImageSize);
	memcpy(pMemory, sysData, dwImageSize);
	for (ULONG i = 0; i < dwImageSize; i++)
	{
		pMemory[i] ^= 0xd8;
		pMemory[i] ^= 0xcd;
	}
	

	
	MemoryLoadLibrary(pMemory, dwImageSize);
	
	
	free(pMemory);
	return 0;


}